package com.swf.jpa.interceptor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.swf.jpa.framework.annotation.InterceptorList;

public class InterceptorBirdge extends HandlerInterceptorAdapter implements ApplicationContextAware{
	 private static ApplicationContext applicationContext;
	 private static final Map<String,List<Interceptor>> interceptorMap = new HashMap<String, List<Interceptor>>();
	 private static final String URLHEAD="/weborder";
	 private ThreadLocal<String>  url = new ThreadLocal<String>();
	    @Override
	    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
	        InterceptorBirdge.applicationContext = applicationContext;
	    }
	    
	    @Override
	    public boolean preHandle(HttpServletRequest request,
	    		HttpServletResponse response, Object handler) throws Exception {
	    	String requestUrl = request.getRequestURI().substring(URLHEAD.length());
	    	url.set(requestUrl);
	    	if (!interceptorMap.containsKey(requestUrl)){
	    		addInterceptor(requestUrl,handler);
	    	}
	    	System.out.println(interceptorMap.size());
	    	List<Interceptor> interceptors = resolveInterceptor(requestUrl);
	    	if (interceptors!=null){
	    	   for (int i=0; i<interceptors.size(); i++) {
	             if(interceptors.get(i).preIntercept(request, response) == false) {
	                 return false;
	             }
	           }
	    	}
	         //
	         return super.preHandle(request, response, handler);
	    }

	private List<Interceptor> resolveInterceptor(String requestUrl) {
		List<Interceptor> list = interceptorMap.get(requestUrl);
		if (list == null) {
			int index = requestUrl.indexOf('.');
			if (index != -1) {
				requestUrl = requestUrl.substring(0, index);
				list = interceptorMap.get(requestUrl);
			}
		}
		return list;
	}
	    
	    private void addInterceptor(String requestUrl, Object handler) {
	    	HandlerMethod a;
	    	HandlerMethod hm = (HandlerMethod)handler;
	    	
			String methodUrl="";
			String typeUrl="";
			Class c = hm.getBeanType();
			RequestMapping turl = AnnotationUtils.findAnnotation(c, RequestMapping.class);
			if (turl!=null){
				typeUrl = turl.value()[0];
			}
			List<Interceptor> interceptorList =null;
			
			RequestMapping murl = hm.getMethodAnnotation(RequestMapping.class);
			if (murl!=null){
				methodUrl = murl.value()[0];
			}
			InterceptorList list = hm.getMethodAnnotation(InterceptorList.class);
			if (list!=null){
				interceptorList = new ArrayList<Interceptor>();
				Class<Interceptor>[] interceptors = (Class<Interceptor>[]) list.names();
				for (Class<Interceptor> interceptorClass:interceptors){
					Interceptor interceptor = applicationContext.getBean(interceptorClass);
					interceptorList.add(interceptor);
				}
			}
			interceptorMap.put(mergeUrl(typeUrl,methodUrl), interceptorList);
		}

		@Override
	    public void postHandle(HttpServletRequest request,
	    		HttpServletResponse response, Object handler,
	    		ModelAndView modelAndView) throws Exception {
	    	List<Interceptor> interceptors = resolveInterceptor(url.get());
	    	if (interceptors!=null){
	    	  for(int i=interceptors.size(); i>0; i--) {
	              interceptors.get(i-1).postIntercept(request, response);
	          }
	    	}
	    }
	    
	    	    
	    private static String mergeUrl(String typeUrl,String methodUrl){
	    	
	    	if (!typeUrl.startsWith("/")){
	    		typeUrl = "/"+typeUrl;
	    	}
	    	if (!methodUrl.startsWith("/")){
	    		methodUrl = "/"+methodUrl;
	    	}
	    	return typeUrl+methodUrl;
	    }

}
